﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using NAnt.Core;
using System.Globalization;

namespace NAntMenu.Logger
{
	/// <summary>
	/// Interaction logic for BuildOutputDialog.xaml
	/// </summary>
	public partial class BuildOutputDialog : Window
	{
		private BuildOutputModel OutputMessages = new BuildOutputModel();

		public BuildOutputDialog(BuildOutputLogger logger)
		{
			InitializeComponent();

			logger.BuildStart += new BuildOutputLogger.BuildStartEventHandler(logger_BuildStart);
			logger.BuildFinish += new BuildOutputLogger.BuildFinishEventHandler(logger_BuildFinish);
			logger.Info += new BuildOutputLogger.InfoEventHandler(logger_Info);
			logger.Warning += new BuildOutputLogger.WarningEventHandler(logger_Warning);
			logger.Error += new BuildOutputLogger.ErrorEventHandler(logger_Error);

			//default settings
			this.btnErrors.IsChecked = true;

			BindData();

			logger.pool.Release();
		}

		private void BindData()
		{
			this.dgOutputMessages.ItemsSource = this.OutputMessages.Messages
				.Where(x => (btnMessages.IsChecked.Value && x.Level == Level.Info)
				|| (btnWarnings.IsChecked.Value && x.Level == Level.Warning)
				|| (btnErrors.IsChecked.Value && x.Level == Level.Error));

			this.tbErrors.Text = string.Format("{0} Errors", this.OutputMessages.Messages.Count(x => x.Level == Level.Error));
			this.tbWarnings.Text = string.Format("{0} Warnings", this.OutputMessages.Messages.Count(x => x.Level == Level.Warning));
			this.tbMessages.Text = string.Format("{0} Messages", this.OutputMessages.Messages.Count(x => x.Level == Level.Info));
		}

		private void dgOutputMessages_RequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
		{
			e.Handled = true;
		}

		void logger_BuildStart()
		{
			SetStatusText("Building...");
		}

		void logger_BuildFinish(Exception error, int errors, int warnings)
		{
			if (error == null)
			{
				if ((errors == 0) && (warnings == 0))
				{
					SetStatusText("BUILD SUCCEEDED");
				}
				else
				{
					SetStatusText(string.Format(CultureInfo.InvariantCulture,
						"BUILD SUCCEEDED - {0} non-fatal error(s), {1} warning(s)",
						errors, warnings));
				}
			}
			else
			{
				if ((errors == 0) && (warnings == 0))
				{
					SetStatusText("BUILD FAILED");
				}
				else
				{
					SetStatusText(string.Format(CultureInfo.InvariantCulture,
						"BUILD FAILED - {0} non-fatal error(s), {1} warning(s)",
						errors, warnings));
				}
			}
		}

		private void logger_Error(string message)
		{
			AddMessage(Level.Error, message);
		}

		private void logger_Warning(string message)
		{
			AddMessage(Level.Warning, message);
		}

		private void logger_Info(string message)
		{
			AddMessage(Level.Info, message);
		}

		private void AddMessage(Level level, string message)
		{
			Dispatcher.BeginInvoke(new Action(() => {
				this.OutputMessages.Messages.Add(new OutputMessage(level, message));

				BindData();

				if (dgOutputMessages.Items.Count > 0)
				{
					var border = VisualTreeHelper.GetChild(dgOutputMessages, 0) as Decorator;
					if (border != null)
					{
						var scroll = border.Child as ScrollViewer;
						if (scroll != null) scroll.ScrollToEnd();
					}
				}
			}));
		}

		private void SetStatusText(string message)
		{
			Dispatcher.BeginInvoke(new Action(() => {
				tbStatusBar.Text = message;
			}));
		}

		private void btnErrors_Checked(object sender, RoutedEventArgs e)
		{
			BindData();
		}

		private void btnWarnings_Checked(object sender, RoutedEventArgs e)
		{
			BindData();
		}

		private void btnMessages_Checked(object sender, RoutedEventArgs e)
		{
			BindData();
		}
	}
}
